package ua.tach.shortl.logic;

import com.badlogic.gdx.graphics.GL10;

public class Switch {
	private Rail[] rails = { Rail.NULL, Rail.NULL };
	private boolean[] railDir = {true, true };
	private Link parent;
	public int linkDir;
	public Semaphore sem = Semaphore.NULL;
	private int state;
	private int locked;
	private Train lockedBy;

	public Switch(Link p, int d) {
		state = 0;
		linkDir = d;
		parent = p;
		locked = 0;
	}

	public void addRail (Rail r, boolean d) {
		if(rails[0] == Rail.NULL) {
			rails[0] = r;
			railDir[0] = d;
		} else {
			// check if the same fail
			if (rails[0].rotation == r.rotation && rails[0].getRailSize()==r.getRailSize())	return;
			rails[1] = r;
			railDir[1] = d;
		}
	}

	public int getRailCount() {
		if (rails[1] == Rail.NULL)
			if (rails[0] == Rail.NULL) {
				return 0;
			} else return 1;
		return 2;
	}

	public int getSemType() {
		if (sem == Semaphore.NULL) return 0;
		return sem.semType;
	}

	public boolean checkRail() {
		return (getRail() != Rail.NULL );
	}

	public void setSemaphor (int type) {
		// Possible types:
		// 0 - no semaphors
		// 1 - switch
		// 2 - light
		// 3 - tupik
		if (type == 0) {
			sem = Semaphore.NULL;
			Country.removeSwitch(this);
			state = 0; // return to open state
		} else {
			if (sem == Semaphore.NULL) {
				sem = new Semaphore(parent.index, type, linkDir);
				if (sem.semType != 3)
					Country.addSwitch(this);
				sem.setType( type );
			} else {
				if (sem.semType == 3)
					Country.addSwitch(this);
				sem.setType( type );
				Country.chgSwitch(this);
			}
			sem.setSignal(state, rails[state].getRailDir(this));
		}
	}

	public boolean isFree () {
		return (rails[0] == Rail.NULL || rails[1] == Rail.NULL);
	}

	public boolean isMine (Rail r) {
		return (rails[0] == r || rails[1] == r);
	}

	public void setLock(Train tr) {
		if (locked == 0 || lockedBy != tr) {
			locked = tr.trainSize;
			lockedBy = tr;
		} else {
			--locked;
			if (locked==0) lockedBy = Train.NULL;
		}
	}
	
	public void unlock(Train tr) {
		if (lockedBy == tr) {
			locked=0;
			lockedBy = Train.NULL;
		}
	}

	public boolean click() {
		if (locked != 0) {
			System.out.println("Click "+this+ " locked "+locked);
			return false;
		}
//		if (sem.semType == 2 ) {// lights swapped
//			Switch s = parent.getSw((linkDir+2)%4);
//			if (s.sem.semType == 2) {
//				return s.clickForce();
//			}
//		}
		state = (state==1)?0:1;
		sem.setSignal(state, rails[state].getRailDir(this));
		return true;
	}

//	public boolean clickForce() {
//		if (locked != 0) return false;
//		state = (state==1)?0:1;
//		sem.setSignal(state, rails[state].getRailDir(this));
//		return true;
//	}

	public Rail getRail () {
		return rails[state];
	}

	public boolean getRailDir () {
		return railDir[state];
	}

	public Switch getNext () {
		int nextIndex = (linkDir+2)%4;
		return parent.getSw(nextIndex);
	}

	public Link getParent() {
		return parent;
	}

	public void render(GL10 gl) {
		sem.render(gl, state);
	}

	public static class NullSwitch extends Switch implements Null {
        private NullSwitch() {
                super(null, 0);
        }

        public boolean isFree() {
        	return true;
        }

		@Override
		public void render(GL10 gl) {
		}

		public int getRailCount() {
			return 0;
		}

		public Rail getRail () {
			return Rail.NULL;
		}

		public int getSemType () {
			return 0;
		}

		public void setSemaphor (int type) {
		}

		@Override public String toString() {
		    StringBuilder result = new StringBuilder();
		    result.append(" SwitchNULL");
		    return result.toString();
		  }
	}

	public static final Switch NULL = new NullSwitch();

	@Override public String toString() {
	    StringBuilder result = new StringBuilder();
	    result.append(" Switch"+linkDir + " at " + parent);
	    return result.toString();
	  }

}
